/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package trace;

/**
 *
 * @author phil
 */
public class CBranch {

    private int misPrediction;
    private int count;
    private int lookbackhistory;
    private int LOOKBACK_MASK;

    private Branch[] predictorTable;

    public int getMisPrediction() {
        return misPrediction;
    }

    public int getCount() {
        return count;
    }

    public CBranch(int h, int n) {
        predictorTable = new Branch[(1<<h)];
        lookbackhistory = 0;
        LOOKBACK_MASK = (1<<h) - 1;
        initPredictorTable(n);
    }

    private void initPredictorTable(int n) {
        for (int i = 0; i < predictorTable.length; i++) {
            predictorTable[i] = new Branch(n);
        }
    }

    private void updateLookBackState(int outcome) {
            lookbackhistory = lookbackhistory<<1;
            lookbackhistory += outcome;
            lookbackhistory &= LOOKBACK_MASK;
    }

    public int updatePrediction(int outcome) {
        int prediction = predictorTable[lookbackhistory].predictionBufferUpdate(outcome);
        if (prediction == outcome) {
            // Good job!
        } else {
            misPrediction++;
        }
        count++;
        updateLookBackState(outcome);
        return prediction;
    }

}
